package com.xt.wikiperfumapi.filter;

import com.xt.wikiperfumapi.model.UserInfo;
import com.xt.wikiperfumapi.service.AuthUserDetailService;
import com.xt.wikiperfumapi.service.impl.UserInfoServiceImpl;
import com.xt.wikiperfumapi.util.EncryptionUtils;
import com.xt.wikiperfumapi.util.JwtUtil;
import io.jsonwebtoken.Claims;
import jakarta.annotation.Resource;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;

/**
 * @author 24862
 */
@Component
@Slf4j
public class JwtFilter extends OncePerRequestFilter {

    @Resource
    JwtUtil jwtUtil;

    @Resource
    AuthUserDetailService userService;

    @Resource
    UserInfoServiceImpl userLoginInfoService;

    @Resource
    EncryptionUtils encryptionUtils;

    /**
     * 主要用于token请求头校验
     * 从token里面获取jwt然后再取出username对应的uuid,通过uuid来获取用户的信息
     */
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response
            ,FilterChain filterChain)
            throws  ServletException, IOException {
        String jwtToken = request.getHeader("token");//从请求头中获取token
        if (jwtToken != null && !jwtToken.isEmpty() && jwtUtil.checkToken(jwtToken)){
            try {//token可用
                Claims claims = jwtUtil.getTokenBody(jwtToken);
                String uuidValue = (String) claims.get("uuid");//这里取出uuid
                String uuid = encryptionUtils.de(uuidValue);
                UserInfo byId = userLoginInfoService.getById(uuid);
                UserDetails user = userService.loadUserByUsername(byId.getUsername());
                if (user != null){
                    UsernamePasswordAuthenticationToken auth =
                            new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
                    SecurityContextHolder.getContext().setAuthentication(auth);
                }
            } catch (Exception e){
                log.error(e.getMessage());
            }
        }else {
            log.warn("token is null or empty or out of time, probably user is not log in !");
        }
        filterChain.doFilter(request, response);//继续过滤
    }
}
